package com.crowntit.infrastructure.adapter.repository;

import com.alibaba.fastjson2.JSON;
import com.crowntit.domain.order.adapter.event.PaySuccessMessageEvent;
import com.crowntit.domain.order.adapter.repository.IOrderRepository;
import com.crowntit.domain.order.model.aggregate.CreateOrderAggregate;
import com.crowntit.domain.order.model.entity.*;
import com.crowntit.domain.order.model.valobj.OrderStatusVO;
import com.crowntit.infrastructure.dao.IOrderDao;
import com.crowntit.infrastructure.dao.po.PayOrder;
import com.crowntit.infrastructure.event.EventPublisher;
import com.crowntit.types.enums.GroupBuyServiceResponseStatusEnum;
import com.crowntit.types.event.BaseEvent;
import com.google.common.eventbus.EventBus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Slf4j
@Repository
public class OrderRepository implements IOrderRepository {

    @Resource
    private IOrderDao orderDao;

    @Resource
    private PaySuccessMessageEvent paySuccessMessageEvent;

    @Resource
    private EventBus eventBus;

    @Resource
    private EventPublisher publisher;

    @Value("${spring.rabbitmq.config.producer.topic_order_pay_success.routing_key}")
    private String routingKey;

    @Override
    public void doSaveOrder(CreateOrderAggregate orderAggregate) {
        String userId = orderAggregate.getUserId();
        ProductEntity productEntity = orderAggregate.getProduct();
        OrderEntity orderEntity = orderAggregate.getOrder();
        GroupBuyLockInfoEntity groupBuyInfo = orderAggregate.getGroupBuyInfo();

        PayOrder order = PayOrder.builder()
                .userId(userId)
                .productId(productEntity.getProductId())
                .productName(productEntity.getProductName())
                .orderId(orderEntity.getOrderId())
                .totalAmount(orderEntity.getTotalAmount())
                .orderStatus(orderEntity.getStatus().getCode())
                .originalPrice(groupBuyInfo.getOriginalPrice())
                .deductionPrice(groupBuyInfo.getDeductionPrice())
                .payPrice(groupBuyInfo.getPayPrice())
                .gbmOutTradeNo(groupBuyInfo.getGbmOutTradeNo())
                .isGroupBuy(groupBuyInfo.getIsGroupBuy())
                .groupBuyServiceResponseStatus(groupBuyInfo.getGroupBuyServiceResponseStatus())
                .build();

        log.info("insert入参: {}", JSON.toJSONString(order));
        orderDao.insert(order);
    }

    @Override
    public OrderEntity queryUnPayOrder(ShopCartEntity shopCart) {
        PayOrder orderReq = PayOrder.builder()
                .userId(shopCart.getUserId())
                .productId(shopCart.getProductId())
                .build();
        PayOrder unPayOrder = orderDao.queryUnPayOrder(orderReq);
        if (null == unPayOrder) return null;

        // 3. 返回结果
        return OrderEntity.builder()
                .productId(unPayOrder.getProductId())
                .productName(unPayOrder.getProductName())
                .orderId(unPayOrder.getOrderId())
                .status(OrderStatusVO.valueOf(unPayOrder.getOrderStatus()))
                .orderTime(unPayOrder.getOrderTime())
                .totalAmount(unPayOrder.getTotalAmount())
                .payUrl(unPayOrder.getPayUrl())
                .originalPrice(unPayOrder.getOriginalPrice())
                .deductionPrice(unPayOrder.getDeductionPrice())
                .payPrice(unPayOrder.getPayPrice())
                .gbmOutTradeNo(unPayOrder.getGbmOutTradeNo())
                .isGroupBuy(unPayOrder.getIsGroupBuy())
                .groupBuyServiceResponseStatus(unPayOrder.getGroupBuyServiceResponseStatus())
                .build();
    }

    @Override
    public void updateOrderPayInfo(PayOrderEntity payOrder) {
        PayOrder payOrderReq = PayOrder.builder()
                .payUrl(payOrder.getPayUrl())
                .orderId(payOrder.getOrderId())
                .orderStatus(payOrder.getStatus().getCode())
                .userId(payOrder.getUserId())
                .build();
        orderDao.updateOrderPayUrlInfo(payOrderReq);
    }

    @Override
    public void updateOrderGroupBuyInfo(OrderEntity payOrder) throws Exception {
        String orderId = payOrder.getOrderId();
        BigDecimal originalPrice = payOrder.getOriginalPrice();
        BigDecimal deductionPrice = payOrder.getDeductionPrice();
        BigDecimal payPrice = payOrder.getPayPrice();
        String gbmOutTradeNo = payOrder.getGbmOutTradeNo();
        Integer isGroupBuy = payOrder.getIsGroupBuy();
        String groupBuyServiceResponseStatus = payOrder.getGroupBuyServiceResponseStatus();

        PayOrder payOrderReq = PayOrder.builder()
                .orderId(orderId)
                .originalPrice(originalPrice)
                .deductionPrice(deductionPrice)
                .payPrice(payPrice)
                .gbmOutTradeNo(gbmOutTradeNo)
                .isGroupBuy(isGroupBuy)
                .groupBuyServiceResponseStatus(groupBuyServiceResponseStatus)
                .build();
        Integer result = orderDao.updateOrderGroupBuyInfo(payOrderReq);

        if (result == null || result!= 1){
            throw new Exception("数据库更新记录行数为0");
        }
    }

    @Override
    public void changeOrderPaySuccess(OrderPaySuccessEntity paySuccessEntity) {
        String orderId = paySuccessEntity.getOrderId();
        GroupBuyServiceResponseStatusEnum paySettlementResStatus = paySuccessEntity.getPaySettlementResStatus();

        PayOrder payOrderReq = new PayOrder();
        payOrderReq.setOrderId(orderId);
        payOrderReq.setOrderStatus(OrderStatusVO.PAY_SUCCESS.getCode());
        orderDao.changeOrderPaySuccess(payOrderReq);
    }

    @Override
    public void changeOrderGroupBuyStatus(GroupBuySettlementInfoEntity settlementInfoEntity) {
        orderDao.changeOrderGroupBuyStatus(PayOrder.builder()
                .groupBuyServiceResponseStatus(settlementInfoEntity.getGroupBuyServiceResponseStatus())
                .orderId(settlementInfoEntity.getOrderId())
                .build());
    }

    @Override
    public GroupBuyStatusEntity queryOrderGroupBuyStatusByOrderId(String orderId) {
        PayOrder order = orderDao.queryPayOrderByOrderId(orderId);
        return GroupBuyStatusEntity.builder()
                .isGroupBuy(order.getIsGroupBuy())
                .gbmOutTradeNo(order.getGbmOutTradeNo())
                .orderId(orderId)
                .userId(order.getUserId())
                .build();
    }

    @Override
    public List<String> queryTimeoutCloseOrder() {
        return orderDao.queryTimeoutCloseOrder();
    }

    @Override
    public List<String> queryNoPayNotifyOrder() {
        return orderDao.queryNoPayNotifyOrder();
    }

    @Override
    public boolean changeOrderClose(String orderId) {
        return orderDao.changeOrderClose(orderId);
    }

    @Override
    public void changeGroupBuyOrdersStatus(GroupBuyNotifyEntity groupBuyNotifyEntity) throws Exception {
        List<String> gbmOutTradeNoList = groupBuyNotifyEntity.getGbmOutTradeNoList();
        String groupBuyTeamStatus = groupBuyNotifyEntity.getGroupBuyTeamStatus();

//        Integer result = 0;
        if ("success".equals(groupBuyTeamStatus)){
            log.info("团购回调-回调信息为success");
            List<PayOrder> orders = orderDao.queryOrdersByGbmOutTradeNos(gbmOutTradeNoList);
            if (orders == null || orders.isEmpty()){
                return;
            }

            log.info("团购回调-修改数据库相关订单状态");
//            result = orderDao.changeOrdersSuccessByGbmOutTradeNos(gbmOutTradeNoList);

            // 发货通知
            log.info("团购回调-发布发货通知");
            orders.forEach(order -> {
                BaseEvent.EventMessage<PaySuccessMessageEvent.PaySuccessMassage> paySuccessMassageEventMessage = paySuccessMessageEvent.buildEventMessage(PaySuccessMessageEvent.PaySuccessMassage.builder()
                        .gbmOutTradeNo(order.getGbmOutTradeNo())
                        .orderId(order.getOrderId())
                        .userId(order.getUserId())
                        .build());
                PaySuccessMessageEvent.PaySuccessMassage data = paySuccessMassageEventMessage.getData();
                String dataStr = JSON.toJSONString(data);
//                eventBus.post(dataStr);
                publisher.publish(routingKey, dataStr);
            });
        } else if ("fail".equals(groupBuyTeamStatus)){
            log.info("团购回调-回调信息为fail");
            log.info("团购回调-修改数据库相关订单状态");
//            result = orderDao.changeOrdersCloseByGbmOutTradeNos(gbmOutTradeNoList);
        }
    }
}
